home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-04-30 | 13.7 KB | 562 lines | [TEXT/MPS ] |
- /*
- File: StreamLogApp.cp
-
- Contains: Stream logging application
-
-
- Copyright: © 1995 by Apple Computer, Inc., all rights reserved.
-
- */
-
- #include "StreamLogApp.h"
- #include "Time.h"
- #include "CTextDoc.h"
- #include "CDirtyText.h"
- #include <PP_Messages.h>
-
- #include <LApplication.h>
- #include <LGrowZone.h>
- #include <LWindow.h>
- #include <LScroller.h>
- #include <LPrintout.h>
- #include <LPlaceHolder.h>
-
- #include <UMemoryMgr.h>
- #include <UDrawingState.h>
- #include <UPowerTools.h>
- #include <URegistrar.h>
- #include <UDesktop.h>
- #include <SegLoad.h>
-
- #include <StandardFile.h>
-
- #include <Types.h>
-
- // ===========================================================================
- // • Main Program
- // ===========================================================================
-
- void main(void)
- {
- // Set Debugging options
- #ifdef Debug_Throw
- gDebugThrow = debugAction_Alert;
- #endif
-
- #ifdef Debug_Signal
- gDebugSignal = debugAction_Alert;
- #endif
-
- InitializeHeap(3); // Initialize Memory Manager
- // Parameter is number of Master Pointer
- // blocks to allocate
-
- // Initialize standard Toolbox managers
- UQDGlobals::InitializeToolbox(&qd);
-
- #ifdef Debug_Signal // Check for missing MBAR, which
- CheckForInitialMBAR(); // probably means that there is no
- #endif // project resource file
-
-
- new LGrowZone(20000); // Install a GrowZone function to catch
- // low memory situations.
- // Parameter is size of reserve memory
- // block to allocated. The first time
- // the GrowZone function is called,
- // there will be at least this much
- // memory left (so you'll have enough
- // memory to alert the user or finish
- // what you are doing).
-
- StreamLogApp theApp; // Create instance of your Application
- theApp.Run(); // class and run it
- }
-
-
- char* LongToString(char* numStr, unsigned long val, Boolean doSign)
- {
- char tempStr[16];
- int ix, digit, len;
- if ( doSign && ((long)val) < 0 )
- {
- val = (unsigned long)(-(long)val);
- OTStrCopy(tempStr, "-");
- }
- else
- OTStrCopy(tempStr, " ");
- ix = 1;
- do
- {
- digit = (int)(val % 10);
- val /= 10;
- tempStr[ix++] = digit | 0x30;
- } while (val != 0);
- len = ix;
- *numStr = *tempStr;
- for (ix = 1; ix < len; ix++)
- numStr[len - ix] = tempStr[ix];
- numStr[len] = '\0';
- return numStr;
- }
-
- char* ShortToString(char* numStr, short val)
- {
- return LongToString(numStr, val, true);
- }
-
- enum
- {
- kOTLvlFatal = 0,
- kOTLvlNonfatal = 1,
- kOTLvlExtFatal = 2,
- kOTLvlExtNonfatal = 3,
- kOTLvlUserErr = 4,
- kOTLvlInfoErr = 5,
- kOTLvlInfoOnly = 6
- };
- ;
-
- char* LevelToString(char* lvlStr, char level)
- {
- switch (level)
- {
- case kOTLvlFatal:
- OTStrCopy(lvlStr, "OT Fatal ");
- break;
-
- case kOTLvlNonfatal:
- OTStrCopy(lvlStr, "OT Nonfatal");
- break;
-
- case kOTLvlExtFatal:
- OTStrCopy(lvlStr, "Ext Fatal ");
- break;
-
- case kOTLvlExtNonfatal:
- OTStrCopy(lvlStr, "Ext Nonfatal");
- break;
-
- case kOTLvlUserErr:
- OTStrCopy(lvlStr, "User ");
- break;
-
- case kOTLvlInfoErr:
- OTStrCopy(lvlStr, "Error ");
- break;
-
- case kOTLvlInfoOnly:
- OTStrCopy(lvlStr, "Info ");
- break;
-
- default:
- OTStrCopy(lvlStr, "Unknown ");
- break;
- }
- return lvlStr;
- }
-
- char* FlagToString(char* flgStr, char flag)
- {
- flgStr[0] = '\0';
-
- if (flag & SL_TRACE)
- OTStrCat(flgStr, "Trace ");
- if (flag & SL_ERROR)
- OTStrCat(flgStr, "Error ");
- if (flag & SL_CONSOLE)
- OTStrCat(flgStr, "Console ");
-
- if (flag & SL_FATAL)
- OTStrCat(flgStr, "Fatal ");
- if (flag & SL_NOTIFY)
- OTStrCat(flgStr, "Notify ");
- if (flag & SL_WARN)
- OTStrCat(flgStr, "Warning ");
- if (flag & SL_NOTE)
- OTStrCat(flgStr, "Notice ");
-
- return flgStr;
- }
-
- StreamLogApp* streamLogApp;
-
- typedef OTBuffer* (*MyReadMessage)(OTReadInfo*);
-
- pascal void NotifyRoutine(void* fd, OTEventCode code,
- OTResult,void*)
- {
- static gBaseMS = 0;
- char outStr[1024], tempStr[64];
- OTBuffer* otbuffer;
- OTReadInfo readInfo;
- OTBuffer* mp;
- log_ctl* entryInfo;
-
- // DebugStr((const unsigned char *)"\pEntered Notify Proc");
- switch (code) {
- case kSIGNALEVENT+SIGPOLL:
- readInfo.fType = (UInt32)-2;
- readInfo.fCommand = 0;
- otbuffer = OTReadMessage((StreamRef)fd, &readInfo);
- while ( otbuffer != NULL )
- {
- if ( (otbuffer->fType == M_PROTO || otbuffer->fType == M_PCPROTO) &&
- otbuffer->fLen == sizeof(log_ctl) )
- {
- entryInfo = (log_ctl*)otbuffer->fData;
- outStr[0] = '\015';
- OTStrCat(outStr, "Time: ");
- strftime(outStr + 1, sizeof(outStr) - 1, "%a, %b %d @ %H:%M:%S.",
- localtime((const time_t*)&entryInfo->ttime));
- if ( gBaseMS == 0 )
- {
- gBaseMS = entryInfo->ltime;
- OTStrCat(outStr, "000");
- }
- else
- {
- UInt32 val = (entryInfo->ltime - gBaseMS) % 1000;
- size_t len = OTStrLength(outStr);
- outStr[len++] = (val / 100) + '0';
- val = val % 100;
- outStr[len++] = (val / 10) + '0';
- outStr[len++] = (val % 10) + '0';
- outStr[len] = '\0';
- }
- OTStrCat(outStr, "\015 Mid: ");
- OTStrCat(outStr, ShortToString(tempStr, entryInfo->mid));
- OTStrCat(outStr, " Sid: ");
- OTStrCat(outStr, ShortToString(tempStr, entryInfo->sid));
- OTStrCat(outStr, " Flag: ");
- OTStrCat(outStr, FlagToString(tempStr, entryInfo->flags));
- OTStrCat(outStr, " Level: ");
- OTStrCat(outStr, LevelToString(tempStr, entryInfo->level));
- OTStrCat(outStr, "\015 ");
- mp = otbuffer->fNext;
- /* Loop reading trace messages and printing them on stdout. */
- while ( mp != NULL )
- {
- if ( mp->fType == M_DATA )
- {
- size_t toCat;
- size_t len = OTStrLength(outStr);
-
- if ( mp->fLen + len < sizeof(outStr) - 2 )
- toCat = mp->fLen;
- else
- toCat = sizeof(outStr) - len - 2;
- OTMemcpy(outStr + len, (char*)mp->fData, toCat);
- len += toCat;
- //
- // Put a Carriage return in case user message does not have it
- //
- outStr[len] = '\0';
- if ( len > 1 )
- {
- size_t ix;
- int which;
- if ( entryInfo->flags & SL_ERROR ) // If SL_ERROR the Window 2
- which = 1;
- else
- which = 0;
- for ( ix = 0; ix < len; ++ix )
- if ( ((streamLogApp->fFillPtr[which] + 1) & kBufferMask) != streamLogApp->fEmptyPtr[which] )
- {
- streamLogApp->fBuffer[which][streamLogApp->fFillPtr[which]++] = outStr[ix];
- streamLogApp->fFillPtr[which] &= kBufferMask;
- }
- }
- else
- DebugStr((unsigned char *)"mp->fData is null");
- }
- mp = mp->fNext;
- }
- }
- // Release the OTBuffer
- OTReleaseBuffer(otbuffer);
-
- // Try for another message
- otbuffer = OTReadMessage((StreamRef)fd, &readInfo);
- }
- break;
- default:
- DebugStr((unsigned char *)"Unknown code in NotifyRoutine");
- break;
- }
- }
-
- extern int errno;
-
- char parameter[4][4] = {
- "log",
- "all",
- "all",
- "all"
- };
-
- #define MI_LOG_DEVICE "/dev/log"
- #define O_RDWR 0x02
-
- void StreamLogApp::OpenStream(strioctl* stri)
- {
- // char buf[LOGMSGSZ];
- OSStatus err;
-
-
- /* Open a stream to the log device. */
- fLogStream = OTStreamOpen(MI_LOG_DEVICE, O_RDWR, &err);
- if ( err != noErr ) {
- // perror("couldn't open log device");
- // AlertUser(kPrintManagerErrStrings, eCannotOpenStreamDialog);
- ExitToShell();
- }
-
- /* Set STREAM as non-blocking and Asynchronous */
- OTStreamSetNonBlocking(fLogStream);
- // OTStreamSetAsynchronous(gLogStream);
-
- /* Register as the trace logger. */
-
- {
- struct trace_ids tracep;
-
- stri->ic_cmd = I_TRCLOG;
- stri->ic_timout = -1;
- stri->ic_dp = (char *)&tracep;
- stri->ic_len = sizeof(tracep);
-
- /* Default is to get all messages from all modules. */
- tracep.ti_mid = -1;
- tracep.ti_sid = -1;
- tracep.ti_level = (char)-1;
- err = OTStreamIoctl(fLogStream, I_STR, stri);
- }
-
- if ( err != kOTNoError ) {
- // fprintf(stderr, "ERROR: strace already running\n");
- // AlertUser(kPrintManagerErrStrings, eStreamAlreadyRunningDialog);
- ExitToShell();
- }
- /* Register as the error logger. */
-
- {
- struct trace_ids tracep;
-
- stri->ic_cmd = I_ERRLOG;
- stri->ic_timout = -1;
- stri->ic_dp = (char *)&tracep;
- stri->ic_len = sizeof(tracep);
-
- /* Default is to get all messages from all modules. */
- tracep.ti_mid = -1;
- tracep.ti_sid = -1;
- tracep.ti_level = (char)-1;
- err = OTStreamIoctl(fLogStream, I_STR, stri);
- }
-
- if ( err != kOTNoError ) {
- // fprintf(stderr, "ERROR: strace already running\n");
- // AlertUser(kPrintManagerErrStrings, eStreamAlreadyRunningDialog);
- ExitToShell();
- }
- err = OTStreamIoctl(fLogStream, I_SETSIG,
- (void*)(S_INPUT | S_RDNORM | S_RDBAND | S_HIPRI | S_OUTPUT | S_WRNORM |
- S_WRBAND | S_MSG | S_ERROR | S_HANGUP | S_BANDURG));
-
- if ( err != kOTNoError ) {
- // fprintf(stderr, "ERROR: strace already running\n");
- // AlertUser(kPrintManagerErrStrings, eStreamAlreadyRunningDialog);
- ExitToShell();
- }
-
- err = OTInstallStreamNotifier(fLogStream, NotifyRoutine, (void*)fLogStream);
- if ( err != noErr ) {
- // AlertUser(kPrintManagerErrStrings, eCantInstallNotifyProcDialog);
- ExitToShell();
- }
- streamLogApp = this;
- }
-
- // ===========================================================================
- // • StreamLogApp Class
- // ===========================================================================
-
- // ---------------------------------------------------------------------------
- // • StreamLogApp
- // ---------------------------------------------------------------------------
- // Constructor
-
- StreamLogApp::StreamLogApp()
- {
- // Register classes for objects created from 'PPob' resources
- URegistrar::RegisterClass('wind', (ClassCreatorFunc) LWindow::CreateWindowStream);
- URegistrar::RegisterClass('scrl', (ClassCreatorFunc) LScroller::CreateScrollerStream);
- URegistrar::RegisterClass('Dtxt', (ClassCreatorFunc) CDirtyText::CreateDirtyTextStream);
- URegistrar::RegisterClass('plac', (ClassCreatorFunc) LPlaceHolder::CreatePlaceHolderStream);
- URegistrar::RegisterClass('prto', (ClassCreatorFunc) LPrintout::CreatePrintoutStream);
- URegistrar::RegisterClass('view', (ClassCreatorFunc) LView::CreateViewStream);
-
- fTraceDoc = new CTextDoc(this, nil);
- fErrorDoc = new CTextDoc(this, nil);
-
- fTraceDoc->SetDescriptor((ConstStr255Param)"\pTrace Log");
- fErrorDoc->SetDescriptor((ConstStr255Param)"\pError Log");
-
- struct strioctl stri;
- fFillPtr[0] = fEmptyPtr[0] = fFillPtr[1] = fEmptyPtr[1] = 0;
- fLogStream = (TSTREAM*)0;
- OSStatus err;
- err = InitOpenTransport();
- if ( err == kOTNoError )
- OpenStream(&stri);
- }
-
-
- // ---------------------------------------------------------------------------
- // • ~StreamLogApp
- // ---------------------------------------------------------------------------
- // Destructor
-
- StreamLogApp::~StreamLogApp()
- {
- if (fLogStream)
- OTStreamClose(fLogStream);
-
- CloseOpenTransport(); // safe to call even if InitLibraryManager failed
-
- }
-
- void
- StreamLogApp::UseIdleTime(
- const EventRecord &inMacEvent)
- {
- char outStr[128];
-
- for (int window = 0; window < 2; window++)
- {
- if (fEmptyPtr[window] != fFillPtr[window])
- {
- int iy = 0;
- while (fEmptyPtr[window] != fFillPtr[window] && iy < sizeof(outStr))
- {
- outStr[iy++] = fBuffer[window][fEmptyPtr[window]++];
- fEmptyPtr[window] &= kBufferMask;
- }
- outStr[iy] = '\0';
- if (window == 0)
- fTraceDoc->OutString(outStr,iy);
- else
- fErrorDoc->OutString(outStr, iy);
- }
- }
-
- LDocApplication::UseIdleTime(inMacEvent);
- }
-
-
- // ---------------------------------------------------------------------------
- // • ObeyCommand
- // ---------------------------------------------------------------------------
- // Respond to commands
-
- Boolean
- StreamLogApp::ObeyCommand(
- CommandT inCommand,
- void *ioParam)
- {
- Boolean cmdHandled = true;
-
- switch (inCommand) {
-
- // +++ Add cases here for the commands you handle
- // Remember to add same cases to FindCommandStatus below
- // to enable/disable the menu items for the commands
-
- default:
- cmdHandled = LDocApplication::ObeyCommand(inCommand, ioParam);
- break;
- }
-
- return cmdHandled;
- }
-
-
- // ---------------------------------------------------------------------------
- // • FindCommandStatus
- // ---------------------------------------------------------------------------
- // Pass back status of a (menu) command
-
- void
- StreamLogApp::FindCommandStatus(
- CommandT inCommand,
- Boolean &outEnabled,
- Boolean &outUsesMark,
- Char16 &outMark,
- Str255 outName)
- {
- outUsesMark = false;
-
- switch (inCommand) {
-
- case cmd_New:
- case cmd_Open:
- case cmd_Close:
- outEnabled = false; // Query has reached the top of a command
- outUsesMark = false; // chain without any object dealing with
- break;
-
- default:
- LDocApplication::FindCommandStatus(inCommand, outEnabled, outUsesMark,
- outMark, outName);
- break;
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // • OpenDocument
- // ---------------------------------------------------------------------------
- // Open a Document file
-
- void
- StreamLogApp::OpenDocument(
- FSSpec *inMacFSSpec)
- {
- CTextDoc *theDoc = new CTextDoc(this, inMacFSSpec);
- }
-
-
- // ---------------------------------------------------------------------------
- // • MakeNewDocument
- // ---------------------------------------------------------------------------
- // Create a new Document
-
- LModelObject*
- StreamLogApp::MakeNewDocument()
- {
- CTextDoc *theDoc = new CTextDoc(this, nil);
- return theDoc;
- }
-
-
- // ---------------------------------------------------------------------------
- // • ChooseDocument
- // ---------------------------------------------------------------------------
- // Prompt the user to select a document to open
-
- void
- StreamLogApp::ChooseDocument()
- {
- StandardFileReply macFileReply;
- SFTypeList typeList;
-
- UDesktop::Deactivate();
- typeList[0] = 'TEXT';
- ::StandardGetFile(nil, 1, typeList, &macFileReply);
- UDesktop::Activate();
- if (macFileReply.sfGood) {
- OpenDocument(&macFileReply.sfFile);
- }
- }
-